#include "qs_config.h"
#include "qs_log.h"

#include "qs_sched.h"
#include "qs_ble_protocol.h"
#include "qs_usart.h"

#define RX_BUFFER_SIZE          50

static qs_ble_protocol_on_rx_cmd_handle_s m_on_rx_cmd_handle = NULL;
static qs_ble_protocol_on_rx_key_handle_s m_on_rx_key_handle = NULL;

static uint8_t tx_buffer[RX_BUFFER_SIZE];
static uint8_t rx_buffer[RX_BUFFER_SIZE];
static uint8_t rx_buffer_index = 0;
static uint8_t rx_com_timeout_timer = 0;
static uint32_t keys_result = 0;
static uint16_t keys_timeout_timer = 0;

static void on_uart_rx_data(uint8_t data)
{
    if(rx_buffer_index < RX_BUFFER_SIZE)
        rx_buffer[rx_buffer_index ++] = data;
}

static void on_10ms_handle(void)
{
    if(rx_com_timeout_timer > 0) {
        rx_com_timeout_timer --;
    }
    if(keys_timeout_timer > 0) {
        keys_timeout_timer --;
        if(keys_timeout_timer == 0) {
            keys_result = 0;
        }
    }
}

void qs_ble_protocol_data_send(qs_ble_protocol_t* p_frame, uint8_t size)
{
    unsigned char cnt,buf;
    memcpy(tx_buffer, p_frame->daten, size);
          
    buf=tx_buffer[0];
    for(cnt=1;cnt<size;cnt++)
        buf^=tx_buffer[cnt];
				
    tx_buffer[size]=buf;
		
    qs_usart_data_send(tx_buffer,size+1);
}
void qs_ble_protocol_init(void)
{

    qs_usart_event_handler_set(on_uart_rx_data, NULL);
    qs_usart_init();
    qs_on_ble_protocol_10ms_handle_set(on_10ms_handle);
}
uint8_t crc_cal(uint8_t* p_data, uint8_t size)
{
    uint8_t crc = p_data[0];
    for(uint8_t i = 1;i < size;i++) {
        crc ^= p_data[i];
    }
    return crc;
}


uint32_t qs_ble_keys_result_get(void)
{
    return keys_result;
}
void qs_ble_protocol_data_process(void)
{
    uint8_t rx_index = rx_buffer_index;
    qs_ble_protocol_t* p_frame = (qs_ble_protocol_t*)rx_buffer;
    static uint8_t last_rx_index = 0;
    
    if(last_rx_index != rx_index) {
        last_rx_index = rx_index;
        rx_com_timeout_timer = 20;
    }
    
    
    
    if(rx_index > rx_buffer[0] && rx_buffer[rx_index - 1] == crc_cal(rx_buffer, rx_index-1)) {
        if(p_frame->type == 0x02) {                   
            keys_result = p_frame->keys.value;
            keys_timeout_timer = 50;
            if(m_on_rx_key_handle) {
                m_on_rx_key_handle();
            }
        } else if(p_frame->type == 0x03) {             
            if(m_on_rx_cmd_handle ) {
//                QS_LOG_INFO("ble code %x param1 %x param2 %x param3 %x\r\n",p_frame->cmd.code,p_frame->cmd.param,p_frame->cmd.param1,p_frame->cmd.param2);
                m_on_rx_cmd_handle(p_frame->cmd.code, p_frame->cmd.param,p_frame->cmd.param1,p_frame->cmd.param2);
                
            }
        } 
        memset(rx_buffer, 0, RX_BUFFER_SIZE);
        rx_buffer_index = 0;
    } 
    if(rx_com_timeout_timer == 0 && rx_index != 0) {
//        QS_LOG_INFO("rx len %d\r\n", rx_buffer_index);
        for(int i = 0;i < rx_buffer_index;i++) {
//            QS_LOG_INFO("%x ", rx_buffer[i]);
        }
//        QS_LOG_INFO("\r\n ");
        memset(rx_buffer, 0, RX_BUFFER_SIZE);
        rx_buffer_index = 0;
        
    }

}
void qs_ble_protocol_on_rx_key_handle_set(qs_ble_protocol_on_rx_key_handle_s on_rx_key_handle)
{
    m_on_rx_key_handle = on_rx_key_handle;
}
void qs_ble_protocol_on_rx_cmd_handle_set(qs_ble_protocol_on_rx_cmd_handle_s on_rx_cmd_handle)
{
    m_on_rx_cmd_handle = on_rx_cmd_handle;
}